package com.ihg.hiex.admin.web.controller.session.during;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.ihg.hiex.admin.entity.dto.CalibrationAnchorScoreMapper;
import com.ihg.hiex.admin.entity.security.Login;
import com.ihg.hiex.admin.service.session.SessionDuringService;
import com.ihg.hiex.admin.service.session.SessionTaskService;
import com.ihg.hiex.admin.web.resolver.Secure;
import com.ihg.hiex.entity.session.during.SessionAnchorScoreType;
import com.ihg.hiex.entity.session.during.SessionCalibration;
import com.ihg.hiex.entity.session.during.SessionCalibrationAnchorScore;
import com.ihg.hiex.entity.session.during.SessionCalibrationComment;
import com.ihg.hiex.entity.session.during.SessionCalibrationCompetency;
import com.ihg.hiex.entity.session.during.SessionCalibrationRecommendation;
import com.ihg.hiex.entity.session.participator.Type;
import com.ihg.hiex.entity.session.task.SessionTask;

/**
 * 
 * @author mohanlan
 *        
 */
@Controller
@RequestMapping("/sessions/{sessionId}/peer-calibrations")
@MenuSetting("menu-consolidation-day")
public class DevelopmentReportWritingController {
    
    @Autowired
    private SessionDuringService sessionDuringService;
    
    @Autowired
    private SessionTaskService sessionTaskService;
    
    /**
     * 
     * @param login
     * @param sessionId
     * @param calibrationId
     * @return
     */
    @MenuSetting(value = "submenu-session-during-development-day")
    @RequestMapping(value = "/{calibrationId}/edit-competency-evaluation", method = RequestMethod.GET)
    public ModelAndView editCompetencyEvaluation(@Secure Login login, @PathVariable("sessionId") Long sessionId, @PathVariable("calibrationId") Long calibrationId) {
        
        ModelAndView modelAndView = new ModelAndView("session/during/development-day/edit-competency-evaluation");
        
        SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(calibrationId);
        modelAndView.addObject("sessionCalibration", sessionCalibration);
        
        List<SessionCalibrationCompetency> competencies = sessionDuringService.listSessionCalibrationCompetency(sessionCalibration);
        modelAndView.addObject("competencies", competencies);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param sessionId
     * @param calibrationId
     * @param names
     * @param results
     * @return
     */
    @MenuSetting(value = "submenu-session-during-development-day")
    @RequestMapping(value = "/{calibrationId}/edit-competency-evaluation", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onEditCompetencyEvaluation(@Secure Login login,
                                                               @PathVariable("sessionId") Long sessionId,
                                                               @PathVariable("calibrationId") Long calibrationId,
                                                               @RequestParam(name = "competencyName") List<String> names,
                                                               @RequestParam(name = "competencyResult") List<SessionAnchorScoreType> results) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(calibrationId);
            List<SessionCalibrationCompetency> competencies = sessionDuringService.listSessionCalibrationCompetency(sessionCalibration);
            
            sessionDuringService.editCompetency(competencies, names, results);
            
            httpResult.success().message("edit success");
            
        } catch (Exception e) {
            httpResult.fail("500").message("edit failed..");
        }
        
        return httpResult;
    }
    
    /**
     * 
     * @param login
     * @param sessionId
     * @param calibrationId
     * @return
     */
    @MenuSetting(value = "submenu-session-during-development-day")
    @RequestMapping(value = "/{calibrationId}/edit-readiness-recommendation", method = RequestMethod.GET)
    public ModelAndView editReadinessRecommendation(@Secure Login login, @PathVariable("sessionId") Long sessionId, @PathVariable("calibrationId") Long calibrationId) {
        
        ModelAndView modelAndView = new ModelAndView("session/during/development-day/edit-readiness-recommendation");
        
        SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(calibrationId);
        modelAndView.addObject("sessionCalibration", sessionCalibration);
        
        SessionCalibrationRecommendation sessionCalibrationRecommendation = sessionDuringService.loadSessionCalibrationRecommendation(sessionCalibration);
        modelAndView.addObject("sessionCalibrationRecommendation", sessionCalibrationRecommendation);
        
        modelAndView.addObject("session", sessionCalibration.getSession());
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param sessionId
     * @param calibrationId
     * @return
     */
    @MenuSetting(value = "submenu-session-during-development-day")
    @RequestMapping(value = "/{calibrationId}/edit-recommendations", method = RequestMethod.GET)
    public ModelAndView editRecommendations(@Secure Login login, @PathVariable("sessionId") Long sessionId, @PathVariable("calibrationId") Long calibrationId) {
        
        ModelAndView modelAndView = new ModelAndView("session/during/development-day/edit-development-recommendations");
        
        SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(calibrationId);
        modelAndView.addObject("sessionCalibration", sessionCalibration);
        
        // load sessionCalibrationCompetency
        List<SessionCalibrationCompetency> sessionCalibrationCompetencies = sessionDuringService.listSessionCalibrationCompetency(sessionCalibration);
        modelAndView.addObject("sessionCalibrationCompetencies", sessionCalibrationCompetencies);
        
     // list strength and development needs anchorScore
        Map<String, List<SessionCalibrationAnchorScore>> strongAnchorScores = sessionDuringService.listSessionCalibrationAnchorScores(sessionCalibrationCompetencies, true);
        Map<String, List<CalibrationAnchorScoreMapper>> strongResult = new HashMap<String, List<CalibrationAnchorScoreMapper>>();
        for(String key : strongAnchorScores.keySet() ) {
            List<CalibrationAnchorScoreMapper> mappers = new ArrayList<CalibrationAnchorScoreMapper>();
            for(SessionCalibrationAnchorScore score : strongAnchorScores.get(key)) {
                mappers.add(new CalibrationAnchorScoreMapper(score));
            }
            strongResult.put(key, mappers);
        }
        
        Map<String, List<SessionCalibrationAnchorScore>> weakAnchorScores = sessionDuringService.listSessionCalibrationAnchorScores(sessionCalibrationCompetencies, false);
        Map<String, List<CalibrationAnchorScoreMapper>> weakResult = new HashMap<String, List<CalibrationAnchorScoreMapper>>();
        for(String key : weakAnchorScores.keySet() ) {
            List<CalibrationAnchorScoreMapper> mappers = new ArrayList<CalibrationAnchorScoreMapper>();
            for(SessionCalibrationAnchorScore score : weakAnchorScores.get(key)) {
                mappers.add(new CalibrationAnchorScoreMapper(score));
            }
            weakResult.put(key, mappers);
        }
        
        SessionCalibrationComment comment = sessionDuringService.loadSessionCalibrationComment(sessionCalibration);
        modelAndView.addObject("comment", comment);
        
        Map<String, SessionCalibrationCompetency> competency = CollectionUtils.constructMapValue(sessionCalibrationCompetencies, "name");
        modelAndView.addObject("competency", competency);
        
        modelAndView.addObject("strongAnchorScores", strongResult);
        modelAndView.addObject("weakAnchorScores", weakResult);
        modelAndView.addObject("id", sessionId);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param sessionId
     * @param calibrationId
     * @return
     */
    @RequestMapping(value = "/{calibrationId}/report-submit", method = RequestMethod.GET)
    public ModelAndView submitReport(@Secure Login login, @PathVariable("sessionId") Long sessionId, @PathVariable("calibrationId") Long calibrationId) {
        
        ModelAndView modelAndView = new ModelAndView("session/during/development-day/submit-report");
        
        SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(calibrationId);
        modelAndView.addObject("sessionCalibration", sessionCalibration);
        
        return modelAndView;
        
    }
    
    
    /**
     * 
     * @param login
     * @param sessionId
     * @param calibrationId
     * @return
     */
    @RequestMapping(value = "/{calibrationId}/report-submit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onSubmitReport(@Secure Login login,
                                                   @PathVariable("sessionId") Long sessionId,
                                                   @PathVariable("calibrationId") Long calibrationId){
        
        HttpResult httpResult = new HttpResult();
        
        try {

            SessionCalibration sessionCalibration = sessionDuringService.loadSessionCalibration(calibrationId);
            SessionTask sessionTask = sessionTaskService.load(sessionCalibration.getSession(), sessionCalibration.getLeadAssessor(), sessionCalibration.getDelegate(), Type.ASSESSOR, "Peer Calibration Report");
            
            sessionDuringService.reportSubmit(sessionCalibration, sessionTask, login);
            
            httpResult.success().message("edit success");
            
        } catch (BusinessException e) {
            httpResult.fail("500").message(e.getMessage());
        } catch (Exception e) {
            httpResult.fail("500").message("edit failed..");
        }
        
        return httpResult;
    }
    
}
